#!/usr/bin/env python
# -*- coding:utf-8 -*-
# えきから時刻表の列車別詳細時刻表からデータを抽出し、sliteDBファイルに保存
#
# installing BeautifulSoup:
#        http://www.crummy.com/software/BeautifulSoup/
#        check python ver and get 3.0xxx or 3.1xxx, and python setup.py install
import locale
import optparse
import sys
import types
import urllib2
import EkikaraDb
import getTimetableLog
import ParseEkikara
import PageOpener
import TrainUpDown


def main():
    CONSOLE_ENCODE = locale.getpreferredencoding()
    logger = getTimetableLog.logging.getLogger("gettimetable")
    # parse command line
    optParser = optparse.OptionParser(usage="%prog -d DBFILE [options] [URL [ URL... ]]", version="%prog 0.4")
    optParser.add_option("-p", "--proxy",
                         dest="proxy",
                         help="proxy if you need. (OK: hogehoge.com:8080 ,NG: http://hogehoge.com:8080)", metavar="URL")
    optParser.add_option("-s", "--status",
                         action="store_true",
                         dest="status",
                         help="print status messages.")
    optParser.add_option("-d", "--db-file",
                         dest="dbFile",
                         default="out.sqlite",
                         help="sqlite db file. If nothing then make, If exist then update this.",
                         metavar="DBFILE")
    # --timeout and --retry options are extend connection timeout. for subway :-)
    optParser.add_option("", "--timeout",
                         action="store",
                         type="float",
                         dest="timeout",
                         help="set timeout", metavar="SEC")
    optParser.add_option("", "--retry",
                         action="store",
                         type="int",
                         dest="retry",
                         help="set retry count max", metavar="COUNT")
    (OPTIONS, args) = optParser.parse_args()
    db = EkikaraDb.EkikaraDb(logger=logger, filename=OPTIONS.dbFile)
    #--------- main
    if OPTIONS.timeout and OPTIONS.retry:
        pageOpener = PageOpener.PageOpener(logger,
                                           proxy=OPTIONS.proxy,
                                           timeout=OPTIONS.timeout,
                                           retryMax=OPTIONS.retry)
    else:
        pageOpener = PageOpener.PageOpener(logger,
                                           proxy=OPTIONS.proxy)
    parser = ParseEkikara.ParseEkikara(logger=logger,
                                       status_option=OPTIONS.status,
                                       console_encode=CONSOLE_ENCODE)
    upDownObj = TrainUpDown.TrainUpDown(logger)
    try:
        for url in args:
            logger.info(u"start parsing: %s" % (url))
            if OPTIONS.status:
                sys.stderr.write((u"\nstart parsing: %s\n" % (url)).encode(CONSOLE_ENCODE))
            attr = parser.getTimeTableAttr(pageOpener, url)
            updown = upDownObj.getUpDown(attr)
            if updown == "":
                updown = 'down'  # 不明な場合はdown扱い
            target = EkikaraDb.Timetable(db=db,
                                         target_timetable_id=db.addTimetableAttr(company=attr['company'],
                                                                               railway_line=attr['line'],
                                                                               updown=updown,
                                                                               day=attr['day'],
                                                                               direction=attr['direction']),
                                         logger=logger)
            stationList = parser.getStationList(pageOpener, url, updown)
            target.setLineStation(stationList)
            train_order = target.getMaxTrainOrder() + 1
            for detailUrl in parser.getDetails(pageOpener, url):
                if not target.isExistTrainUrl(detailUrl):
                    train = parser.getTrain(pageOpener, detailUrl)
                    if isinstance(train['number'], types.StringTypes):
                        if not target.isExistSameTrain(train['number'], detailUrl):
                            train.update(parser.extractTrainName(train['name']))
                            train_order += 1
                            target.setTrain(train_order, train)
                            strDbWroteTrain = u"wroteDb[%s][%s][%s][%s][%s][%s]" % (train['number'],
                                                                                  train['type_prefix'],
                                                                                  train['type'],
                                                                                  train['name'],
                                                                                  train['gou'],
                                                                                  train['url'],)
                            logger.debug(strDbWroteTrain)
                            if OPTIONS.status:
                                sys.stderr.write((strDbWroteTrain).encode(CONSOLE_ENCODE))
                    elif isinstance(train['number'], types.ListType):
                        for singleTrain in parser.splitTrain(train):
                            if not target.isExistSameTrain(singleTrain['number'], detailUrl):
                                singleTrain.update(parser.extractTrainName(singleTrain['name']))
                                train_order += 1
                                target.setTrain(train_order, singleTrain)
                                strDbWroteSingleTrain = u"wroteDb[%s][%s][%s][%s][%s][%s]" % (singleTrain['number'],
                                                                                            singleTrain['type_prefix'],
                                                                                            singleTrain['type'],
                                                                                            singleTrain['name'],
                                                                                            singleTrain['gou'],
                                                                                            singleTrain['url'],)
                                logger.debug(strDbWroteSingleTrain)
                                if OPTIONS.status:
                                    sys.stderr.write((strDbWroteSingleTrain).encode(CONSOLE_ENCODE))
            logger.info(u"parsing end: %s" % (url))
            if OPTIONS.status:
                sys.stderr.write((u"\nparsing end: %s\n" % (url)).encode(CONSOLE_ENCODE))
    except PageOpener.PageOpenerRetryError, e:
        #urllib2.URLError: <urlopen error [Errno 11001] getaddrinfo failed>
        logger.error(u"Over retry count;retryMax=[%d], retryCount=[%d]\n" % (e.retryMax, e.retryCount))
        sys.stderr.write((u"Over retry count;retryMax=[%d], retryCount=[%d]\n" % (e.retryMax,
                                                                                e.retryCount)).encode(CONSOLE_ENCODE))
        sys.exit(1)  # 終了するよ
    except urllib2.HTTPError, e:
        logger.error(u"invalid URL[%s][%d].\nPlease check url.\n" % (url, e.code))
        sys.stderr.write((u"invalid URL[%s][%d].\nPlease check url.\n" % (url, e.code)).encode(CONSOLE_ENCODE))
        sys.exit(1)  # 終了するよ
    except urllib2.URLError, e:
        #urllib2.URLError: <urlopen error [Errno 11001] getaddrinfo failed>
        logger.error(u"Can not open URL[%s].\n%s\nPlease check your internet access.\n" % (url, e.reason))
        sys.stderr.write((u"Can not open URL[%s].\n%s\nPlease check your internet access.\n" % (url,
                                                                                              e.reason)).encode(CONSOLE_ENCODE))
        sys.exit(1)  # 終了するよ


if __name__ == "__main__":
    main()
